package persistencia;


import dominio.*;
import java.util.List;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

public class PersistenciaLocacao {
    //private List<Locacao> locacoes = new ArrayList<Locacao>();
        private static PersistenciaLocacao InstanciaLocacao;
        private Connection conn;
        
   /**
 * Conexão com o banco de dados
 * 
 */
        public PersistenciaLocacao () {
                Conecta c = Conecta.getConnection();
                this.conn = c.conn;
        }
	 
/**
 * 
 * Singleton. Usado para que haja apenas uma conexão com o banco sendo usada no sistema
 * 
 */
     public static PersistenciaLocacao getInstance(){
	if(InstanciaLocacao == null) {
                        	InstanciaLocacao = new PersistenciaLocacao();
	    }
	 return InstanciaLocacao;
     }     

/* Função que busca todos as locações
* contidas no banco
* @return listaLocacao
*/
     public ArrayList<Locacao> listarLocacoes () {
                ArrayList<Locacao> locacoes = new ArrayList<Locacao>();
                Statement statement;
                ResultSet result;
                try {
                        statement = conn.createStatement();
                        result = statement.executeQuery("SELECT * FROM Locacao");
                        while (result.next()){
                                Locacao l = new Locacao(result.getString("fkTipoLocacao"), result.getDouble("kmSaida"), result.getDate("dataSaida"),
                                                                            result.getInt("previsaoDias"), result.getLong("fkCpfCliente"), result.getString("fkPlacaVeiculo"));
                                locacoes.add(l);  
                        }
                        return locacoes;
                } catch (SQLException e) {
                    System.out.println("Erro em listar locacoes");
                        //Log.getLoginstance(null).error("Ocorreu um erro: "+e.getMessage());
                        return null;
                }
        }

/* Função que busca por todas as locações já finalizadas
* @return listaLocacao
*/
    public List<Locacao> consultarPorFinalizadas(){
        
                ArrayList<Locacao> locacoes = new ArrayList<Locacao>();
                Statement statement;
                ResultSet result;
                try {
                        statement = conn.createStatement();
                        result = statement.executeQuery("SELECT * FROM Locacao WHERE finalizada = "+"'"+1+"'");
                        while (result.next()){
                                Locacao l = new Locacao(result.getString("fkTipoLocacao"), result.getDouble("kmSaida"), result.getDate("dataSaida"),
                                                                            result.getInt("previsaoDias"), result.getLong("fkCpfCliente"), result.getString("fkPlacaVeiculo"));
                               locacoes.add(l);
                        }
                        return locacoes;
                } catch (SQLException e) {
                    System.out.println("Erro em consultar por locacoes finalizadas");
                        //Log.getLoginstance(null).error("Ocorreu um erro: "+e.getMessage());
                        return null;
                }
    }
   
   public List<Locacao> consultarPorCliente(long cpf){
                ArrayList<Locacao> locacoes = new ArrayList<Locacao>();
                Statement statement;
                ResultSet result;
                try {
                        statement = conn.createStatement();
                        result = statement.executeQuery("SELECT * FROM Locacao WHERE fkCpfCliente = "+"'"+cpf+"'");
                        while (result.next()){
                                Locacao l = new Locacao(result.getString("fkTipoLocacao"), result.getDouble("kmSaida"), result.getDate("dataSaida"),
                                                                            result.getInt("previsaoDias"), result.getLong("fkCpfCliente"), result.getString("fkPlacaVeiculo"));
                               locacoes.add(l);
                        }
                        return locacoes;
                } catch (SQLException e) {
                    System.out.println("Erro em consultar por cliente");
                        //Log.getLoginstance(null).error("Ocorreu um erro: "+e.getMessage());
                        return null;
                }
    }

/* Função que busca por todas as locações ainda abertas
* @return listaLocacao
*/
    public ArrayList<Locacao> consultaLocacaoAberta() throws SQLException {
               //CONSULTAR E CALCULAR VALOR CASO A ENTREGA FOSSE FEITA NA DATA DA CONSULTA
        
                ArrayList<Locacao> locacoes = new ArrayList<Locacao>();
                Statement statement;
                ResultSet result, result2, result3;
                Double valorTotal = 0.0;
                Double valor=0.0, valor1=0.0;

                try {
                        statement = conn.createStatement();
                        result = statement.executeQuery("SELECT * FROM TipoLocacao WHERE tipo = "+"'"+"por quilometragem"+"'");
                        result2 = statement.executeQuery("SELECT * FROM Locacao WHERE finalizada = 0");
                        result3 = statement.executeQuery("SELECT * FROM TipoLocacao WHERE tipo = "+"'"+"quilometragem livre"+"'");
                        while (result2.next()){
                                Locacao l = new Locacao(result2.getString("fkTipoLocacao"), result2.getDouble("kmSaida"), result2.getDate("dataSaida"),
                                                                            result2.getInt("previsaoDias"), result2.getLong("fkCpfCliente"), result2.getString("fkPlacaVeiculo"));
                               locacoes.add(l);
                                           System.out.println("CPF do Cliente: "+ result2.getLong("fkCpfCliente"));
                                           System.out.println("Veículo Locado: "+ result2.getLong("fkPlacaVeiculo"));
                                           System.out.println("Tipo da Locação: "+ result2.getLong("fkTipoLocacao"));
                                           System.out.println("Data Saída: "+ result2.getLong("dataSaida"));
                                           System.out.println("Data Entrega: "+ result2.getLong("dataDevolucao"));
                                           System.out.println("Quilometragem Inicial: "+ result2.getLong("kmSaida"));
                                           System.out.println();
                                           
                               if(result2.getString("fkTipoLocacao").equals("por quilometragem")) {
                                        valor1 = valor1 +(result.getDouble("taxaBase") * result2.getInt("previsaoDias"));
                                }
                               else {                       
                                      valor = valor + (result3.getDouble("taxaBase") + result2.getInt("previsaoDias"));
                               }      
                        }
                } catch (SQLException e) {
                    System.out.println("Erro em consultar locação aberta");
                        //Log.getLoginstance(null).error("Ocorreu um erro: "+e.getMessage());
                }
 
                valorTotal = valor+valor1;
                System.out.println("Valor Total a ser recebido : " + valorTotal);
                return locacoes;
    }

/* Função que busca por todas as locações já finalizadas
* @return listaLocacao
*/
    public ArrayList<Locacao> consultaLocacaoFinalizada () {

                ArrayList<Locacao> locacoes = new ArrayList<Locacao>();
                Statement statement;
                ResultSet result;
                Double valorTotal = 0.0;                
                
                try {
                        statement = conn.createStatement();
                        result = statement.executeQuery("SELECT * FROM Locacao WHERE finalizada = "+"'"+1+"'");
                        while (result.next()){
                                Locacao l = new Locacao(result.getString("fkTipoLocacao"), result.getDouble("kmSaida"), result.getDate("dataSaida"),
                                                                            result.getInt("previsaoDias"), result.getLong("fkCpfCliente"), result.getString("fkPlacaVeiculo"));
                               locacoes.add(l);
                        }
                } catch (SQLException e) {
                    System.out.println("Erro em consultar por locação finalizada");
                        //Log.getLoginstance(null).error("Ocorreu um erro: "+e.getMessage());
                }
                
            //CALCULAR VALOR TOTAL DAS LOCACOES FINALIZADAS
                
            if (locacoes == null) System.out.println("Nenhuma locação finalizada");
            else {
                 for(int i = 0; i < locacoes.size(); i++) {
                        valorTotal = valorTotal + locacoes.get(i).getValorLocacao();            
                 }
            }
            System.out.println("Valor Total das Locações Finalizadas: " + valorTotal);
            return locacoes;
    }
    
    

/* Função que faz o cadastro de uma locação
* @return listaLocacao
*/
    public void cadastroLocacao() throws SQLException, Exception {
     
              int i, nDiarias, nMotoristas;
              int contador = 0;
              String cpf;
              Double kmInicial;
              String placaVeiculoEscolhido, tipoEscolhido;
              String dataHoje;
              Date datah;

             //Encontrar/Cadastrar, se necessario, o cliente que vai fazer a locacao.

            Statement statement;
            ResultSet result;
            try {
                statement = conn.createStatement();
                System.out.println("Digite o CPF do cliente que deseja locar um veículo: ");
                cpf = Console.readString();

                result = statement.executeQuery("SELECT * FROM Veiculo WHERE livre = "+"'"+1+"'");
                    while (result.next()){
                        System.out.println("Veículo: " + contador);
                        System.out.println("Marca: "+result.getString("marca"));
                        System.out.println("Cor: "+result.getString("cor"));
                        System.out.println("Modelo: "+result.getString("modelo"));
                        System.out.println("Tipo: "+result.getString("tipo"));
                        System.out.println("Placa: "+result.getString("placa"));
                        System.out.println("");
                        contador++;
                    }
                    if (contador == 0) { // OU result2 == null
                        System.out.println("Nenhum veículo Livre.");
                    }
                     else {
                            System.out.println("Digite o número da placa do veículo que deseja locar.");
                            placaVeiculoEscolhido = Console.readString();
                            System.out.println("Escolha o tipo: ");
                            tipoEscolhido = Console.readString();

                            System.out.println("Data de hoje: aaaa-mm-dd ");
                            dataHoje = Console.readString();

                   //Determinar número previsto de dias da locação, cadastrar a data de hoje e a quilometragem inicial do veículo.
        
                            System.out.println("Número de dias que deseja permanecer com o veículo: ");
                            nDiarias = Console.readInteger();
                                 while (nDiarias > 90 || nDiarias < 1) {
                                     System.out.println("Número mínimo é de 1 dia e o número máximo é de 90.");
                                     System.out.println("Número de dias que deseja permanecer com o veículo: ");
                                     nDiarias = Console.readInteger();
                                 }

                                 Uteis u = new Uteis();
                            System.out.println("Km Inicial: ");
                            kmInicial = Console.readDouble();

                       //Calcular data de Entrega prevista.
                           String dataEntrega = null;
                           dataEntrega = u.somarDatas(dataHoje, nDiarias);

                           System.out.println("data entrega:"+dataEntrega);
                    System.out.println("Número de motoristas: ");
                    nMotoristas = Console.readInteger();
                //Atualizar banco
               statement.executeUpdate("INSERT INTO Locacao (fkCpfCliente, fkPlacaVeiculo, dataSaida, dataDevolucao, fkIdTipoLocacao, kmSaida, numeroMotoristas, previsaoDias, finalizada)" +
                                                "values('"+cpf+"','"+placaVeiculoEscolhido+"','"+dataHoje+"','"+dataEntrega+"','"+tipoEscolhido+"','"+kmInicial+"','"+nMotoristas+"','"+nDiarias+"','"+0+"')");
               statement.executeUpdate("UPDATE Veiculo SET livre = '"+0+"'WHERE placa = '"+placaVeiculoEscolhido+"'");

               for(i = 0; i < nMotoristas; i++) {
                     System.out.println("Número a cnh: ");
                     String cnh = Console.readString();
                     statement.executeUpdate("INSERT INTO MotoristaLocacao(fkCnhMotorista,fkPlacaVeiculo,fkDataSaida)" +
                                              "values('"+cnh+"','"+placaVeiculoEscolhido+"','"+dataHoje+"')");
               }
              }
            }catch (SQLException e) {
                System.out.println("Erro em cadastro locacao.");
                System.out.println(e.getMessage());
                    //Log.getLoginstance(null).error("Ocorreu um erro: "+e.getMessage());
            }
            System.out.println("Locação cadastrada com sucesso!");

            }

/* Função que imprime uma lista de locações
* @param listaLocacao
*/
   public void imprimeLista(ArrayList<Locacao> locacoes) {

       for (int i=0; i < locacoes.size(); i++) {
           System.out.println(i);
           System.out.println("CPF do Cliente: "+ locacoes.get(i).getFkCpfCliente());
           System.out.println("Veículo Locado: "+ locacoes.get(i).getFkPlacaVeiculo());
           System.out.println("Tipo da Locação: "+ locacoes.get(i).getFkIdTipoLocacao());
           System.out.println("Data Saída: "+ locacoes.get(i).getDataSaida());
           System.out.println("Data Entrega: "+ locacoes.get(i).getDataDevolucao());
           System.out.println("Quilometragem Inicial: "+ locacoes.get(i).getKmSaida());
           System.out.println();
       }
   }
}
